﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;
using System.Reflection;

namespace SqliteManager
{
    public class ConfigManager<T>where T:new()
    {
        #region -- 简单单例
        protected static ConfigManager<T> _Instance = null;

        public static ConfigManager<T> Instance
        {
            get
            {
                if(_Instance == null)
                {
                    _Instance = new ConfigManager<T>()
                    {
                        _Data = new T(),
                    };
                    _Instance.LoadAll();
                }

                return _Instance;
            }
        }
        #endregion

        protected T _Data;

        public static T Data
        {
            get
            {
                return Instance._Data;
            }
        }

        /// <summary>
        /// 加载所有配置
        /// </summary>
        public void LoadAll()
        {
            //检测文件是否存在
            string path = Path.Combine(Environment.CurrentDirectory, "Config.ini");
            if(!File.Exists(path))
            {
                Logger.Log($"{path} is not exists.");
                return;
            }

            IniFile con = new IniFile(path);

            string SectionID = typeof(T).Name;
            FieldInfo[] fies = typeof(T).GetFields();
            for(int i = 0;i<fies.Length;i++)
            {
                FieldInfo fi = fies[i];
                string str = con.IniReadValue(SectionID, fi.Name);
                if(!string.IsNullOrEmpty(str))
                {
                    fi.SetValue(_Data, str.StringToSystemObjectType(fi.FieldType));
                }
            }

        }
    }

    public class IniFile
    {
        public string path;
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section,
        string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal,
        int size, string filePath);

        public IniFile(string INIPath)
        {
            path = INIPath;
        }

        public void IniWriteValue(string Section, string Key, string Value)
        {
            WritePrivateProfileString(Section, Key, Value, this.path);
        }

        public string IniReadValue(string Section, string Key)
        {
            StringBuilder temp = new StringBuilder(1024);
            int i = GetPrivateProfileString(Section, Key, "", temp, 1024, this.path);
            return temp.ToString();
        }
    }

}
